import Obj from "./Obj";
import Collection from "./Collection";
import UnsupportedOperationException from "../exceptions/UnsupportedOperationException";

/**
 * 不可变的集合。
 *
 * 当这个集合在完成了构造之后，其浅层的值将不再允许发生改变。所有会导致发生改变的方法都会导致{@link UnsupportedOperationException}异常。
 *
 * @param E 需要存储在此集合中的元素类型
 * @see Collection
 * @version 1.0
 */
export default class UnmodifiableCollection<E> extends Obj implements Collection<E> {

  /**
   * 用于存储元素的数组。
   *
   * @private
   * @version 1.0
   */
  private readonly collection: Collection<E>;

  /**
   * 构造一个不可变集合并传入一个初始集合。
   *
   * 在构造完成之后，该集合将不再可变。
   *
   * @param collection 需要存储在此不可变集合中的元素
   * @version 1.0
   */
  public constructor(collection: Collection<E>) {
    super();
    this.collection = collection;
  }

  [Symbol.iterator](): Iterator<E> {
    return this.iterator();
  }

  /**
   * @throws {UnsupportedOperationException} 此方法不被支持
   * @version 1.0
   */
  add(e: E): boolean {
    throw new UnsupportedOperationException(UnmodifiableCollection, this.add);
  }

  /**
   * 返回此集合的容量。
   *
   * @return {number} 返回此结合的容量
   * @version 1.0
   */
  capacity(): number {
    return this.collection.capacity();
  }

  /**
   * @throws {UnsupportedOperationException} 此方法不被支持
   * @version 1.0
   */
  clear(): void {
    this.collection.clear();
  }

  /**
   * 返回此集合是否包含指定的元素。
   *
   * @param e 需要查找的元素
   * @return {boolean} 如果此集合包含该元素，则返回true，否则返回false
   * @version 1.0
   */
  contains(e: E): boolean {
    return this.collection.contains(e);
  }

  equals(b: Obj): boolean {
    return this.collection.equals(b);
  }

  /**
   * @throws {UnsupportedOperationException} 此方法不被支持
   * @version 1.0
   */
  grow(capacity: number): void {
    throw new UnsupportedOperationException(UnmodifiableCollection, this.grow);
  }

  hashCode(): number {
    return this.collection.hashCode();
  }

  /**
   * 返回此集合是否为空。
   *
   * @return {boolean} 如果此集合不包含任何元素，则返回true，否则返回false
   * @version 1.0
   */
  isEmpty(): boolean {
    return this.collection.isEmpty();
  }

  /**
   * 返回此集合是否已满。
   *
   * @return {boolean} 如果此集合存储的元素已到达容量，则返回true，否则返回false。若容量为-1，则永远不会满容量
   */
  isFull(): boolean {
    return this.collection.isFull();
  }

  /**
   * 返回由集合内所有元素组成的迭代器。
   *
   * @return {Iterator} 一个由集合内所有元素组成的迭代器
   * @see Iterator
   * @version 1.0
   */
  iterator(): Iterator<E> {
    return this.collection.iterator();
  }

  /**
   * @throws {UnsupportedOperationException} 此方法不被支持
   * @version 1.0
   */
  remove(e: E): boolean {
    throw new UnsupportedOperationException(UnmodifiableCollection, this.remove);
  }

  /**
   * @throws {UnsupportedOperationException} 此方法不被支持
   * @version 1.0
   */
  removeIf(filter: (e: E) => boolean): boolean {
    throw new UnsupportedOperationException(UnmodifiableCollection, this.removeIf);
  }

  /**
   * @throws {UnsupportedOperationException} 此方法不被支持
   * @param e
   */
  removeFirst(e: E): boolean {
    throw new UnsupportedOperationException(UnmodifiableCollection, this.removeFirst);
  }

  /**
   * 返回此集合中的元素数。
   *
   * @return {number} 返回此集合中的元素数
   * @version 1.0
   */
  size(): number {
    return this.collection.size();
  }

  /**
   * 返回由集合内所有元素组成的数组。
   *
   * 该数组内的元素会是集合中元素的<strong>浅拷贝</strong>，因此后续对集合的操作不会影响到数组的浅层，反之亦然。
   *
   * @return {E[]} 一个由集合内所有元素组成的数组
   * @version 1.0
   */
  toArray(): E[] {
    return this.collection.toArray();
  }

  toString(): string {
    return this.collection.toString();
  }
}
